﻿using System;
using System.Collections;
using System.Collections.Generic;
using NetFramework.HTTP;
using UnityEngine.Networking;

namespace Common.Utils
{
    public delegate void UpdateResult(string _curFile, float _progress);
    public delegate void DownloadProgress(float _progress);

    public class DownloadResult
    {
        public bool IsDone { get; private set; }
        public float Progress { get; private set; }
        public int TotalSize { get; private set; }
        public string CurFile { get; private set; }

        public DownloadResult(int _totalSize, ref UpdateResult _ur)
        {
            _ur = _UpdateDownloadResult;
            IsDone = false;
            Progress = 0.0f;
            TotalSize = _totalSize;
            CurFile = "";
        }

        private void _UpdateDownloadResult(string _curFile, float _progress)
        {
            if (null != _curFile)
                CurFile = _curFile;
            Progress = _progress;
            if (Progress >= 1.0f)
                IsDone = true;
        }
    }

    public class Downloader
    {
        // private int CurrIndex { get; set; }
        public float TotalCount { get; private set; }
        public float DoneCount { get; private set; }
        public int TotalSize { get; private set; }
        public Queue<string[]> UrlList { get; private set; }
        public List<bool> IsDone { get; private set; }

        // event
        private event UpdateResult UpdateResult;
        private event DownloadProgress DownloadProgress;

        public Downloader()
        {
            UrlList = new Queue<string[]>();
            IsDone = new List<bool>();
            Init();
        }

        public Downloader(List<string[]> _urlList)
        {
            UrlList = new Queue<string[]>();
            IsDone = new List<bool>();
            AddItem(_urlList);
            Init();
        }

        private void Init()
        {
            TotalCount = UrlList.Count;
            DoneCount = 0.0f;
            TotalSize = 0;
        }

        public void AddItem(string[] url)
        {
            UrlList.Enqueue(url);
            IsDone.Add(false);
            TotalSize += System.Convert.ToInt32(url[3]);
        }

        public void AddItem(List<string[]> _urlList)
        {
            foreach (string[] item in _urlList)
            {
                AddItem(item);
            }
        }

        public void StartSync()
        {
            _DownLoad();
        }

        public DownloadResult StartAsync()
        {
            TotalCount = UrlList.Count;
            if (TotalCount < 1)
                return null;
            DownloadResult dr = new DownloadResult(TotalSize, ref UpdateResult);
            CoroutineController.Instance.StartCoroutine(_StartAsync());
            return dr;
        }

        private IEnumerator _StartAsync()
        {
            _DownLoad();
            yield return null;
        }

        private void _DownLoad()
        {
            if (UrlList.Count < 1)
                return;

            string[] item = UrlList.Peek();
            string url  = item[0];
            string path = item[1];
            string name = item[2];

            HTTPManager.Instance.DownloadFile(url, path, _OnDownLoadCompleted, _OnDownLooadProgress);
            UpdateResult?.Invoke(name, DoneCount / TotalCount);
        }

        private void _OnDownLoadCompleted(UnityWebRequest _result)
        {
            string[] item = UrlList.Dequeue();
            if (_result.isNetworkError || _result.isHttpError)
            {
                UrlList.Enqueue(item);
                UpdateResult?.Invoke(null, DoneCount / TotalCount);
            }
            else
            {
                DoneCount++;
                UpdateResult?.Invoke(null, DoneCount / TotalCount);

            }
            _DownLoad();
        }


        private void _OnDownLooadProgress(float _progress, ulong compBytes = 0, ulong totalBytes = 0)
        {
            UpdateResult?.Invoke(null, (DoneCount + _progress) / TotalCount);
        }


    }
}

